package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.BindPublicGroupDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PublicGroupSyncService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.RelTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.PublicGroupRabbitMqDTO;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.help.PublicSeniorRuleHelp;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.PublicGroupSeniorService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.ProPermissionEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.ProPermissionModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author lijiangren
 * @version v1.0
 * @date 2022/05/13 10:17
 * @since v1.0
 */
@Service("publicGroupSyncService")
public class PublicGroupSyncServiceImpl implements PublicGroupSyncService {

    private static final Logger LOG = LoggerFactory.getLogger(PublicGroupSyncServiceImpl.class);

    @Resource
    private PackageHelp packageHelp;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PublicGroupSeniorService publicGroupSeniorService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private MessageService messageService;
    @Resource
    private UserModel userModel;
    @Resource
    private ProPermissionModel proPermissionModel;
    @Resource
    private RoleModel roleModel;
    @Resource
    private PublicSeniorRuleHelp publicSeniorRuleHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ClueModel clueModel;
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private IndexTypeModel indexTypeModel;
    /**
     *
     * 通过脚本形式绑定公海分组
     * @param bindPublicGroupDTO
     * @author lijiangren
     * @date 2022-05-18 10 23
     * @since
     * @version
     */
    @Override
    public XbbResponse<BaseVO> bindCustomerPublicGroupByScript(BindPublicGroupDTO bindPublicGroupDTO) throws XbbException {
        XbbResponse<BaseVO> baseVO = new XbbResponse<>();
        String key = bindPublicGroupDTO.getKey();
        Integer byCorpid = bindPublicGroupDTO.getByCorpid();
        try {
            if (!proBaseConfig.getXbbCode().equals(key)) {
                LOG.error("公海客户规则校验 密码错误，停止定时任务！");
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
            }

            if (byCorpid != null && Objects.equals(0,byCorpid)) {
                //需要绑定所属公海的公司
                List<String> syncCorpidCustomer = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.CUSTOMER_PUBLIC_POOL_CHANGE.getAlias());
                if (CollectionsUtil.isNotEmpty(syncCorpidCustomer)) {
                    for (String corpid : syncCorpidCustomer) {
                        //编辑需要同步的公司数据
                        syncBindPublicGroup(corpid,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                    }
                }
            } else {
                //用于运维单独同步某些公司是传入的公司集合
                List<String> corpids = bindPublicGroupDTO.getCorpids();
                if (CollectionsUtil.isNotEmpty(corpids)) {
                    for (String corpid : corpids) {
                        syncBindPublicGroup(corpid,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                    }
                }
            }

            return baseVO;
        } catch (XbbException e) {
            LOG.error("同步绑定客户公海池分组异常",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public XbbResponse<BaseVO> bindCluePublicGroupByScript(BindPublicGroupDTO bindPublicGroupDTO) throws XbbException {
        XbbResponse<BaseVO> baseVO = new XbbResponse<>();
        String key = bindPublicGroupDTO.getKey();
        Integer byCorpid = bindPublicGroupDTO.getByCorpid();
        try {
            if (!proBaseConfig.getXbbCode().equals(key)) {
                LOG.error("公海客户规则校验 密码错误，停止定时任务！");
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
            }

            if (byCorpid != null && Objects.equals(0,byCorpid)) {
                //线索需要绑定所属公海的公司
                List<String> syncCorpidClue = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.CLUE_PUBLIC_POOL_CHANGE.getAlias());
                if (CollectionsUtil.isNotEmpty(syncCorpidClue)) {
                    for (String corpid : syncCorpidClue) {
                        //编辑需要同步的公司数据
                        syncBindPublicGroup(corpid,XbbRefTypeEnum.CLUE.getCode());
                    }
                }
            } else {
                //用于运维单独同步某些公司是传入的公司集合
                List<String> corpids = bindPublicGroupDTO.getCorpids();
                if (CollectionsUtil.isNotEmpty(corpids)) {
                    for (String corpid : corpids) {
                        syncBindPublicGroup(corpid,XbbRefTypeEnum.CLUE.getCode());
                    }
                }
            }

            return baseVO;
        } catch (XbbException e) {
            LOG.error("同步绑定线索公海池分组异常",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     *
     * 通过Mq形式绑定公海分组(新建、导入的（未绑定分组的新数据）)
     * @param publicGroupRabbitMqDTO
     * @author lijiangren
     * @date 2022-05-18 10 23
     * @since
     * @version
     */
    @Override
    public void bindPublicGroupByMq(PublicGroupRabbitMqDTO publicGroupRabbitMqDTO) throws XbbException {
        try {
            LOG.info("消费端收到绑定消息{}",JSON.toJSON(publicGroupRabbitMqDTO));
            //可能主数据未保存成功，导致这边匹配失效问题，这里暂时延迟3秒
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                LOG.error("Thread.sleep", e);
                // 恢复中断状态
                Thread.currentThread().interrupt();
            }
            String corpid = publicGroupRabbitMqDTO.getCorpid();
            Integer businessType = publicGroupRabbitMqDTO.getBusinessType();
            Long formId = publicGroupRabbitMqDTO.getFormId();
            List<Long> dataIdList = publicGroupRabbitMqDTO.getDataIds();
            if (CollectionsUtil.isEmpty(dataIdList)) {
                return;
            }
            //获取该模板下的高级分组
            List<PublicGroupSeniorEntity> publicGroupEntityList = publicGroupSeniorService.getFormListByPriority(corpid, formId);
            List<String> nameList = new ArrayList<>();
            publicGroupEntityList.forEach(item-> nameList.add(item.getName()));
            LOG.info("高级分组{}",JSON.toJSONString(nameList));
            if (CollectionsUtil.isEmpty(publicGroupEntityList)) {
                return;
            }
            //分组字段Attr
            String attr = CustomerManagementEnum.PUBLIC_GROUP.getAttr();
            if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                attr = ClueEnum.PUBLIC_GROUP.getAttr();
            }


            for (PublicGroupSeniorEntity publicGroupSeniorEntity : publicGroupEntityList) {
                if (CollectionsUtil.isEmpty(dataIdList)) {
                    break;
                }
                //每次执行分组规则绑定了的数据ID
                List dealDataIdList = new ArrayList<>();
                JSONArray jsonData = publicGroupSeniorEntity.getJsonData();
                Long groupId = publicGroupSeniorEntity.getId();
                //取个巧 无分组这个字段为空
                if (CollectionsUtil.isNotEmpty(jsonData)) {
                    List<ConditionsEntityExt> groupConditionList = JSONArray.parseArray(jsonData.toJSONString(), ConditionsEntityExt.class);
                    XbbAggregatedPage<PaasFormDataEntityExt> xbbAggregatedPage = getPaasFormDataEntityList(groupConditionList, dataIdList, null,null, formId, businessType, corpid);
                    if (CollectionsUtil.isNotEmpty(xbbAggregatedPage.getContent())) {
                        List<PaasFormDataEntityExt> paasFormDataList = xbbAggregatedPage.getContent();
                        LOG.info("绑定了分组{}",publicGroupSeniorEntity.getName());
                        paasFormDataList.forEach(item -> dealDataIdList.add(item.getDataId()));
                        batchUpdatePublicGroupBySync(paasFormDataList,attr, groupId, businessType,corpid);
                    }
                }
                dataIdList.removeAll(dealDataIdList);
            }

        } catch (Exception e) {
            LOG.error("同步绑定公海池分组异常",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }


    /**
     * 同步数据绑定所属公海数据
     * @param corpid
     */
    private void syncBindPublicGroup(String corpid, Integer businessType) throws XbbException {
        try {
            LOG.info("syncBindPublicGroup_start:" + corpid);
            boolean ultimate = packageHelp.isUltimateWithFeeType(corpid);
            if (!ultimate) {
                LOG.info("该公司非旗舰版，不执行同步数据绑定所属公海数据脚本:corpid=====" + corpid);
                return;
            }
            String publicPoolModelChangeSeniorComplete = RedisPrefixConstant.CUSTOMER_PUBLIC_POOL_MODEL_CHANGE_SENIOR_COMPLETE;
            if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())) {
                publicPoolModelChangeSeniorComplete = RedisPrefixConstant.CLUE_PUBLIC_POOL_MODEL_CHANGE_SENIOR_COMPLETE;
            }
            //判断该公司是否同步完成数据标识
            String value = paasRedisHelper.getValue(publicPoolModelChangeSeniorComplete, corpid);
            if (Objects.isNull(value) || Objects.equals(value, BasicConstant.TWO.toString()) || Objects.equals(value, BasicConstant.THREE.toString())) {
                LOG.info("该公司绑定所属公海已经完成，无需重复执行:corpid=====" + corpid);
                return;
            }

            //绑定分组前需要清空之前绑定分组ID
            removePublicGroup2OldData(corpid,businessType);

            String attr = CustomerManagementEnum.PUBLIC_GROUP.getAttr();
            PushTypeEnum pushTypeEnum = PushTypeEnum.CUSTOMER_PUBLIC_POOL_MODEL_CHANGE_MESSAGE;
            String messageTitle = I18nMessageUtil.getMessage(MessageConstant.CUSTOMER_HIGH_SEAS_POOL);
            if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                attr = ClueEnum.PUBLIC_GROUP.getAttr();
                pushTypeEnum = PushTypeEnum.CLUE_PUBLIC_POOL_MODEL_CHANGE_MESSAGE;
                messageTitle = I18nMessageUtil.getMessage(MessageConstant.CLUE_HIGH_SEAS_POOL);
            }

            //根据业务ID获取所有启用的表单
            List<PaasFormEntityExt> enableFormList = paasFormModel.getFormListDistributor(corpid, businessType, BasicConstant.ZERO);
            if (CollectionsUtil.isEmpty(enableFormList)) {
                return;
            }
            List<Long> formIdList = enableFormList.stream().map(PaasFormEntityExt::getId).collect(Collectors.toList());
            for (Long formId : formIdList) {
                //获取该每个表单的分组对象
                List<PublicGroupSeniorEntity> publicGroupEntityList = publicGroupSeniorService.getFormListByPriority(corpid, formId);
                for (PublicGroupSeniorEntity publicGroupSeniorEntity : publicGroupEntityList) {
                    Long groupId = publicGroupSeniorEntity.getId();
                    JSONArray jsonData = publicGroupSeniorEntity.getJsonData();
                    //取个巧 无分组这个字段为空
                    if (CollectionsUtil.isNotEmpty(jsonData)) {
                        List<ConditionsEntityExt> groupConditionList = JSONArray.parseArray(jsonData.toJSONString(), ConditionsEntityExt.class);
                        //通过ES查询符合该分组条件的总数
                        long totalCount = getCount(groupConditionList, formId, businessType, corpid);
                        LOG.warn("totalCount{}", totalCount);
                        // 每5000条数据进行分页处理，计算分页页数
                        int pageSize = 5000;
                        Long gtId = 0L;
                        int pageNum = (int) (totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize);
                        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
                            XbbAggregatedPage<PaasFormDataEntityExt> xbbAggregatedPage = getPaasFormDataEntityList(groupConditionList, null, gtId, pageSize,formId, businessType, corpid);
                            LOG.warn("本页查询到{}条，进度{}/{}", xbbAggregatedPage.getContent().size(), currentPage, pageNum);
                            List<PaasFormDataEntityExt> paasFormDataList = xbbAggregatedPage.getContent();
                            if (CollectionsUtil.isEmpty(paasFormDataList)) {
                                //未查询到说明没有需要绑定该分组的数据，进入下一轮分组
                                break;
                            }
                            gtId = paasFormDataList.get(paasFormDataList.size() - 1).getDataId();

                            List<Long> idList = new ArrayList<>();
                            for (PaasFormDataEntityExt dataEntityExt : paasFormDataList) {
                                idList.add(dataEntityExt.getDataId());
                            }
                            //多查一次数据库，为了解决ES数据不一致问题（异步更新可能会出现查询重复）
                            if (Objects.equals(businessType,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                                List<CustomerEntityExt> customerEntityListByDb = customerModel.getByKeys(idList, corpid);
                                for (CustomerEntityExt customerEntityExt : customerEntityListByDb) {
                                    String publicGroup = FastJsonHelper.getStringFromFormData(customerEntityExt.getData(), CustomerManagementEnum.PUBLIC_GROUP.getAttr());
                                    if (StringUtil.isNotEmpty(publicGroup)) {
                                        //LOG.warn("有需要移除的");
                                        paasFormDataList.removeIf(item -> Objects.equals(item.getDataId(),customerEntityExt.getId()));
                                    }
                                }
                            } else {
                                List<ClueEntityExt> clueEntityListByDb = clueModel.getByKeys(idList, corpid);
                                for (ClueEntityExt clueEntityExt : clueEntityListByDb) {
                                    String publicGroup = FastJsonHelper.getStringFromFormData(clueEntityExt.getData(), ClueEnum.PUBLIC_GROUP.getAttr());
                                    if (StringUtil.isNotEmpty(publicGroup)) {
                                        //LOG.warn("有需要移除的");
                                        paasFormDataList.removeIf(item -> Objects.equals(item.getDataId(),clueEntityExt.getId()));
                                    }
                                }
                            }

                            batchUpdatePublicGroupBySync(paasFormDataList,attr, groupId, businessType,corpid);
                            //batchUpdatePublicGroup(paasFormDataList,attr, groupId, businessType,corpid);
                        }
                    }
                }
            }

            //发送消息给有切换公海池权限的人员
            List<String> pushUserIds = getUserIdListByPerssionAlias(corpid);
            if (CollectionsUtil.isNotEmpty(pushUserIds)) {
                PushRefTypePojo.Options options = new PushRefTypePojo.Options();
                //为了兼容底层发送消息逻辑需要的数据ID
                List<Long> refIds = Arrays.asList(0L);
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, refIds , 0, DateTimeUtil.getInt(), messageTitle, I18nMessageUtil.getMessage(MessageConstant.PUBLIC_POOL_MODEL_CHANGE_TITLE), null, options);
                messageService.insertPushData(messageRabbitMqDTO, pushTypeEnum);
            }
            //给公海池模式切换打上标识，数据切换完成。
            paasRedisHelper.setValue(publicPoolModelChangeSeniorComplete, corpid, BasicConstant.TWO,  TimeConstant.SECONDS_PER_MONTH);
        } catch (Exception e) {
            LOG.error("publicGroupSyncServiceImpl.syncBindPublicGroup, corpid:" + corpid, e);
        }
    }

    private void removePublicGroup2OldData(String corpid, Integer businessType) {
        try {
            Long startTime = System.currentTimeMillis();
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, SaasMarkEnum.SAAS.getCode());
            String attr = CustomerManagementEnum.PUBLIC_GROUP.getAttr();
            if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())) {
                attr = ClueEnum.PUBLIC_GROUP.getAttr();
            }

            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
            boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
            boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.normalStatus()));
            boolQueryBuilder.filter(existsQuery("data." + attr + ".keyword"));
            boolQueryBuilder.mustNot(termQuery("data." + attr + ".keyword", ""));
            sourceBuilder.query(boolQueryBuilder);

            List<String> fieldList = new ArrayList<>();
            //只需要拿到数据ID更新即可
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            fieldList.add("data." + attr);
            String[] strings = new String[fieldList.size()];
            sourceBuilder.fetchSource(fieldList.toArray(strings),null);
            sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));
            SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
            searchRequest.source(sourceBuilder);
            //通过ES查询需要删除已经绑定的分组数据的总数
            long totalCount = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
            LOG.info("查询到公司：{}有：{}条数据更新",corpid, totalCount);
            //查不到数据，不执行逻辑
            if (Objects.equals(totalCount, 0)) {
                return;
            }

            // 每5000条数据进行分页处理，计算分页页数
            int pageSize = 5000;
            Long gteId = 0L;
            int pageNum = (int) (totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize);
            for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
                //组合需要批量更新的数据对象
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                try {
                    boolQueryBuilder.filter(rangeQuery(FieldTypeEnum.DATAID.getAlias()).gt(gteId));
                    sourceBuilder.query(boolQueryBuilder);
                    PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, pageSize);
                    searchRequest.source(sourceBuilder);
                    XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                    if (Objects.isNull(esEntities) || CollectionsUtil.isEmpty(esEntities.getContent())) {
                        break;
                    }

                    List<PaasFormDataEntityExt> dataEntityExtList = esEntities.getContent();
                    //下一次循环用来作为查询条件。避免重复查询
                    gteId = dataEntityExtList.get(dataEntityExtList.size() - 1).getDataId();
                    for (PaasFormDataEntityExt entity : dataEntityExtList) {
                        JSONObject data = entity.getData();
                        if (Objects.nonNull(data) && StringUtil.isNotEmpty(data.get(attr).toString())) {
                            JSONObject temp = new JSONObject();
                            temp.put(attr, "");
                            UpdateDataEntity updateData = ExplainUtil.getUpdateData(entity.getDataId(), temp, corpid);
                            updateDataEntityList.add(updateData);
                        }
                    }

                    //批量更新
                    if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                        publicSeniorRuleHelp.updateBatch(businessType, corpid, updateDataEntityList);
                        //proUpdateHelp.updateBatch(1, businessType, corpid, updateDataEntityList);

                        LOG.info("{}清空历史数据中绑定公海分组号段{}--{}",updateDataEntityList.size(),updateDataEntityList.get(0).getId(),updateDataEntityList.get(updateDataEntityList.size()-1).getId());
                    }
                } catch (Exception e) {
                    LOG.info("removePublicGroup2OldData公司为：{}清空历史数据中绑定公海分组失败号段{}--{}",corpid,updateDataEntityList.get(0).getId(),updateDataEntityList.get(updateDataEntityList.size()-1).getId());
                }
            }

            Long endTime = System.currentTimeMillis();
            LOG.info("清空历史数据中绑定公海分组需要时间:{}",(endTime - startTime));
            LOG.info("清空历史数据中绑定公海分组条数:{}",totalCount);
        } catch (Exception e) {
            LOG.error("清空历史数据中绑定公海分组失败, corpid:" + corpid, e);
        }

    }

    /**
     * 获取拥有切换数据权限的人
     * @author lijiangren
     * @date 2022-05-25 16 52
     * @since
     * @version
     */
    private List<String> getUserIdListByPerssionAlias(String corpid) {
        ProPermissionEntity proPermissionEntity = proPermissionModel.getByAlias(ProPermissionAliasEnum.SWITCH_PUBLIC_MODE.getAlias());
        if (Objects.nonNull(proPermissionEntity)) {
            List<Integer> roleIds = new ArrayList<>();
            // 查出有切換公海模式的角色
            Integer id = proPermissionEntity.getId();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("isUse", BasicConstant.ONE);
            param.put("permissionsLike", "|" + id + "|");
            List<RoleEntity> entitys = roleModel.findEntitys(param);
            entitys.forEach(item -> roleIds.add(item.getId()));
            return userModel.getUserIdsByRoles(corpid, roleIds);
        }
        return null;
    }

    /**
     * 通过分组规则查询需要绑定的数据
     * @author lijiangren
     * @date 2022-05-16 10 51
     * @since
     * @version
     */
    private XbbAggregatedPage<PaasFormDataEntityExt> getPaasFormDataEntityList(List<ConditionsEntityExt> conditionList, List<Long> dataIdList, Long gtId,  Integer pageSize, Long formId, Integer businessType, String corpid) throws XbbException {
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, SaasMarkEnum.SAAS.getCode());
        String attr = CustomerManagementEnum.PUBLIC_GROUP.getAttr();
        if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())) {
            attr = ClueEnum.PUBLIC_GROUP.getAttr();
        }

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        boolQueryBuilder.filter(termQuery("formId",formId));
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.normalStatus()));
        if (Objects.nonNull(gtId)) {
            boolQueryBuilder.filter(rangeQuery(FieldTypeEnum.DATAID.getAlias()).gt(gtId));
        }
        if (CollectionsUtil.isNotEmpty(dataIdList)) {
            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
        }
        if (CollectionsUtil.isNotEmpty(conditionList)) {
            publicSeniorRuleHelp.addressSearchShouldCondition(conditionList);
            EsUtil.parseCondition(boolQueryBuilder,conditionList, RelTypeEnum.AND.getAlias(), corpid, businessType);
        }
        BoolQueryBuilder emptyBool = new BoolQueryBuilder();
        emptyBool.should(boolQuery().mustNot(existsQuery("data." + attr + ".keyword")));
        emptyBool.should(termQuery("data." + attr + ".keyword", ""));
        emptyBool.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
        boolQueryBuilder.filter(emptyBool);
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        //只需要拿到数据ID更新即可
        fieldList.add(FieldTypeEnum.DATAID.getAlias());

        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);
        sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, 1000);
        if (Objects.nonNull(pageSize)) {
            EsUtil.setPage(sourceBuilder, 0, pageSize);
        }
        if (CollectionsUtil.isNotEmpty(dataIdList)) {
            EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
        }
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        return esEntities;
    }


    private long getCount(List<ConditionsEntityExt> conditionList, Long formId, Integer businessType, String corpid) throws XbbException {
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, SaasMarkEnum.SAAS.getCode());
        String attr = CustomerManagementEnum.PUBLIC_GROUP.getAttr();
        if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())) {
            attr = ClueEnum.PUBLIC_GROUP.getAttr();
        }

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        boolQueryBuilder.filter(termQuery("formId",formId));
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.normalStatus()));

        if (CollectionsUtil.isNotEmpty(conditionList)) {
            publicSeniorRuleHelp.addressSearchShouldCondition(conditionList);
            EsUtil.parseCondition(boolQueryBuilder,conditionList, RelTypeEnum.AND.getAlias(), corpid, businessType);
        }
        BoolQueryBuilder emptyBool = new BoolQueryBuilder();
        emptyBool.should(boolQuery().mustNot(existsQuery("data." + attr + ".keyword")));
        emptyBool.should(termQuery("data." + attr + ".keyword", ""));
        emptyBool.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
        boolQueryBuilder.filter(emptyBool);
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        long count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
        return count;
    }

    /**
     * 同步逻辑更新ES
     */
    private void batchUpdatePublicGroup(List<PaasFormDataEntityExt> paasFormDataList, String attr, Long groupId, Integer businessType, String corpid) throws XbbException {
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            if (CollectionsUtil.isNotEmpty(paasFormDataList)) {
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataList) {
                    //绑定公海分组集合
                    JSONObject temp = new JSONObject();
                    temp.put(attr, String.valueOf(groupId));
                    UpdateDataEntity updateData = ExplainUtil.getUpdateData(paasFormDataEntityExt.getDataId(), temp, corpid);
                    updateDataEntityList.add(updateData);
                }
                //批量绑定公海分组
                if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    publicSeniorRuleHelp.updateBatch(businessType, corpid, updateDataEntityList);
                }
            }
        } catch (Exception e) {
            LOG.info("batchUpdatePublicGroup公司为：{}更新绑定所属分组失败号段{}--{}",corpid,updateDataEntityList.get(0).getId(),updateDataEntityList.get(updateDataEntityList.size()-1).getId());
            LOG.error("batchUpdatePublicGroup更新绑定所属分组错误",e);
        }
    }

    /**
     * 异步逻辑更新ES
     */
    private void batchUpdatePublicGroupBySync(List<PaasFormDataEntityExt> paasFormDataList, String attr, Long groupId, Integer businessType, String corpid) throws XbbException {
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            if (CollectionsUtil.isNotEmpty(paasFormDataList)) {
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataList) {
                    //绑定公海分组集合
                    JSONObject temp = new JSONObject();
                    temp.put(attr, String.valueOf(groupId));
                    UpdateDataEntity updateData = ExplainUtil.getUpdateData(paasFormDataEntityExt.getDataId(), temp, corpid);
                    updateDataEntityList.add(updateData);
                }
                //批量绑定公海分组
                if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    proUpdateHelp.updateBatch(1,businessType, corpid, updateDataEntityList);
                }
            }
        } catch (Exception e) {
            LOG.info("batchUpdatePublicGroup公司为：{}更新绑定所属分组失败号段{}--{}",corpid,updateDataEntityList.get(0).getId(),updateDataEntityList.get(updateDataEntityList.size()-1).getId());
            LOG.error("batchUpdatePublicGroup更新绑定所属分组错误",e);
        }
    }


}
